package com.hotel.BL;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.EntityName;
import com.StatusTitle;
import com.Util;
import com.google.appengine.api.datastore.Entity;
import com.google.appengine.api.datastore.EntityNotFoundException;
import com.google.appengine.api.datastore.FetchOptions;
import com.google.appengine.api.datastore.Key;
import com.google.appengine.api.datastore.KeyFactory;
import com.google.appengine.api.datastore.Query;
import com.google.appengine.api.datastore.Query.CompositeFilterOperator;
import com.google.appengine.api.datastore.Query.Filter;
import com.google.appengine.api.datastore.Query.FilterOperator;
import com.google.appengine.api.datastore.Query.FilterPredicate;
import com.google.appengine.api.datastore.Query.SortDirection;

import data.CleaningStatus;
import data.DNR;
import data.Reservation;
import data.ReservationStatus;
import data.Room;
import data.passingData.ReservationData;

public class DNRLogic extends AbstractBL{
	
	public DNRLogic(HttpServletRequest req,HttpServletResponse resp){
		this.req = req;
		this.resp = resp;
	}

	public DNR AddDNR(long hotelId,long roomId,Date datefrom,Date dateto,String description) throws EntityNotFoundException{
		RoomLogic roomLogic = new RoomLogic(req,resp);
		GenericLogic gLogic = new GenericLogic(req,resp);
		
		CleaningStatus dnr = gLogic.GetCleaningStatus(1,
				StatusTitle.CleaningStatusTitle.DNR);
		
		DNR item = new DNR();
		item.setHotelId(hotelId);
		item.setDate(datefrom);
		item.setDateTo(dateto);
		item.setRoomId(roomId);
		item.setDescription(description);
		
		Key k = datastore.put(item.getEntity());
		item.setId(k.getId());
		item.setKey(k);
		
		if(Util.GetOnlyDate(gLogic.ServerDateFromNightAudit(1)).equals(datefrom)){
			Room room = roomLogic.GetRoom(roomId);
			room.setCleaningStatus(dnr);
			roomLogic.UpdateRoom(room);
		}

		return item;
	}
	
	public DNR GetDNR(long id){
		Key key = KeyFactory.createKey(EntityName.DNR, id);
		try {
			Entity lang = datastore.get(key);
			DNR c = new DNR();
			c.setEntity(lang);
			
			return c;
		} catch (EntityNotFoundException e) {
			return null;
		}
	}
	
	public List<DNR> GetExistDNR(long hotelId,Date date,long roomId){
		Query q = new Query(EntityName.DNR);
		Filter filterhotelId = new FilterPredicate("hotelId",
				FilterOperator.EQUAL, hotelId);
		Filter filterDate = new FilterPredicate("dateTo",
				FilterOperator.GREATER_THAN, date);
		Filter filterroomId = new FilterPredicate("roomId",
				FilterOperator.EQUAL, roomId);
		
		Filter filter = CompositeFilterOperator.and(filterhotelId, filterDate, filterroomId);
		q.setFilter(filter).addSort("dateTo", SortDirection.ASCENDING);
		return GetList(datastore.prepare(q).asList(
				FetchOptions.Builder.withDefaults()));
	}
	
	public List<DNR> GetExistDNR(long hotelId,Date date){
		Query q = new Query(EntityName.DNR);
		Filter filterhotelId = new FilterPredicate("hotelId",
				FilterOperator.EQUAL, hotelId);
		Filter filterDate = new FilterPredicate("dateTo",
				FilterOperator.GREATER_THAN, date);
		
		Filter filter = CompositeFilterOperator.and(filterhotelId, filterDate);
		q.setFilter(filter).addSort("dateTo", SortDirection.ASCENDING);
		return GetList(datastore.prepare(q).asList(
				FetchOptions.Builder.withDefaults()));
	}
	
	public DNR GetDNR(Entity entity)
	{
		if(entity == null) return null;
		DNR item = new DNR();
		item.setEntity(entity);
		return item;
	}
	
	public List<DNR> GetList(List<Entity> entities)
	{
		List<DNR> list = new ArrayList<DNR>();
		for(Entity e : entities)
		{
			DNR t = new DNR();
			t.setEntity(e);
			list.add(t);
		}
		return list;
	}
	
	public List<DNR> GetReservationList(long hotelId,Date date,long span)
	{
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		cal.add(Calendar.DATE, (int) span);

		Query q = new Query(EntityName.DNR);
		
		Filter filterHotel = new FilterPredicate("hotelId",
				FilterOperator.EQUAL, hotelId);
		Filter filterresDate = new FilterPredicate("dateTo",
				FilterOperator.GREATER_THAN_OR_EQUAL, date);
		Filter filter = CompositeFilterOperator.and(filterresDate, filterHotel);
		q.setFilter(filter);
		
		List<DNR> list1 = GetList(datastore.prepare(q).asList(
				FetchOptions.Builder.withDefaults()));
		List<DNR> result = new ArrayList<DNR>();
		
		for(DNR r : list1)
		{
			if(r.getDate().after(Util.addDays(date,span -1)))
				continue;
			result.add(r);
		}

		return result;
	}
	
	public boolean DeleteRoom(long dnrId){
		GenericLogic gLogic = new GenericLogic(req,resp);
		DNR dnr = GetDNR(dnrId);
		
		Key key = KeyFactory.createKey(EntityName.DNR, dnrId);
		datastore.delete(key);
		
		if(Util.GetOnlyDate(gLogic.ServerDateFromNightAudit(1)).equals(dnr.getDate())){

			RoomLogic roomLogic = new RoomLogic(req,resp);
			CleaningStatus insp = gLogic.GetCleaningStatus(1,
					StatusTitle.CleaningStatusTitle.InspectRooms);
			Room room = roomLogic.GetRoom(dnr.getRoomId());
			room.setCleaningStatus(insp);
			roomLogic.UpdateRoom(room);
		}
		return true;
	}
	
	public Reservation DNRtoReservation(DNR dnr){
		Reservation res = new Reservation();
		GenericLogic gLogic = new GenericLogic(req,resp);
		RoomLogic roomLogic = new RoomLogic(req,resp);
		Room room = roomLogic.GetRoom(dnr.getRoomId());
		
		ReservationStatus dnrStatus = gLogic.GetReservationStatus(dnr.getHotelId(), StatusTitle.CleaningStatusTitle.DNR);
		res.setHotelId(dnr.getHotelId());
		res.setDate(dnr.getDate());
		res.setSpan(Util.daysBetween(dnr.getDate(), dnr.getDateTo()));
		res.setRoomString(Long.toString(dnr.getRoomId()));
		res.setRoomTypeString(room.getRoomtypeString());
		res.setNote(dnr.getDescription());
		res.setReservationStatus(dnrStatus);
		res.setAssign(true);
		res.setSellRoom(false);
		res.setId(dnr.getId());
		return res;
	}
	
	public ReservationData DNRtoReservationData(DNR dnr){
		ReservationData res = new ReservationData();
		GenericLogic gLogic = new GenericLogic(req,resp);
		ReservationStatus dnrStatus = gLogic.GetReservationStatus(dnr.getHotelId(), StatusTitle.CleaningStatusTitle.DNR);
		RoomLogic roomLogic = new RoomLogic(req,resp);
		Room room = roomLogic.GetRoom(dnr.getRoomId());
		res.setId(dnr.getId());
		res.setDate(dnr.getDate());
		res.setSpan(Util.daysBetween(dnr.getDate(), dnr.getDateTo()));
		res.setDateTo(dnr.getDateTo());
		res.setRoomNameId(room.getId());
		res.setRoomTypeId(Long.parseLong(room.getRoomtypeString()));
		res.setResStatus(Long.toString(dnrStatus.getId()));
		return res;
	}
	public DNR UpdateDNR(DNR dnr)
	{
		Key key = datastore.put(dnr.getEntity());
		dnr.setId(key.getId());
		dnr.setKey(key);
		return dnr;
	}
}
